package gui;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.SystemColor;
import java.beans.PropertyVetoException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.border.TitledBorder;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

import com.jgoodies.forms.factories.FormFactory;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.RowSpec;
import com.michaelbaranov.microba.calendar.DatePicker;

import data.DepartmentData;
import data.OrderDepartment;
import data.OrderElement;
import data.ProductInfo;

public class ObjectOrderPanel extends JPanel {
	private static final long serialVersionUID = 3261532236110363787L;

	private OrderInfoTabPanel mParent = null;
	private DepartmentData mDepartmentData = null;
	private JTable mTable;
	private JTextField nameTextField;
	private JTextField phoneTextField;
	private DatePicker datePicker;
	private DatePicker datePicker2;
	private JTextField hourTextField;
	private JTextPane commentsTextPane;
	
	private JLabel lblSum;
	private JLabel lblReInvoice;

	// private TableColumnAdjuster mTca;

	/**
	 * Create the panel.
	 * @wbp.parser.constructor
	 */
	public ObjectOrderPanel(OrderInfoTabPanel parent, DepartmentData objectData) {
		setBackground(SystemColor.window);
		mParent = parent;
		mDepartmentData = objectData;

		initGUI();
	}

	@Override
	public void setEnabled(boolean enabled) {
		nameTextField.setEnabled(enabled);
		phoneTextField.setEnabled(enabled);
		datePicker.setEnabled(enabled);
		datePicker2.setEnabled(enabled);
		hourTextField.setEnabled(enabled);
		commentsTextPane.setEnabled(enabled);
		super.setEnabled(enabled);
	}
	
	public ObjectOrderPanel(OrderInfoTabPanel parent, DepartmentData objectData, OrderDepartment orderDepartment) {
		setBackground(SystemColor.window);
		mParent = parent;
		mDepartmentData = objectData;

		initGUI();
		
		nameTextField.setText(orderDepartment.getOrderReceiver());
		phoneTextField.setText(orderDepartment.getContactPhone());
		try {
			datePicker.setDate(orderDepartment.getDate1());
			datePicker2.setDate(orderDepartment.getDate2());
		} catch (PropertyVetoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		hourTextField.setText(orderDepartment.getHour());
		commentsTextPane.setText(orderDepartment.getComments());
		
		int i = 0;
		for (OrderElement element : orderDepartment.getOrderElements()) {
			if (mTable.getRowCount() <= i)
				((DefaultTableModel)mTable.getModel()).addRow(new Object[] { null, null, null, null, null, null, null });
			mTable.setValueAt(MainPanel.getProductByDbId(element.getProductId()), i, 1);
			mTable.setValueAt(element.getPrice(), i, 5);
			mTable.setValueAt(element.getQuantity(), i, 3);
			mTable.setValueAt(element.isReinvoice(), i, 7);
			++i;
		}
	}
	
	public DepartmentData getDepartmentData() {
		return mDepartmentData;
	}

	public OrderDepartment getOrderDepartment() {
		List<OrderElement> elements = new ArrayList<>();
		for (int i = 0; i < mTable.getRowCount(); ++i)
			if (mTable.getValueAt(i, 2) != null && mTable.getValueAt(i, 3) != null)
				elements.add(new OrderElement(((ProductInfo)mTable.getValueAt(i, 1)).getDbId(), (double) mTable.getValueAt(i, 5),
						(int) mTable.getValueAt(i, 3), (boolean) mTable.getValueAt(i, 7)));
		return new OrderDepartment(nameTextField.getText(), phoneTextField.getText(), datePicker.getDate(), datePicker2.getDate(), 
				hourTextField.getText(), commentsTextPane.getText(), elements);
	}
	
	private class DisabledItemsComboBox extends JComboBox<ProductInfo> {
		private static final long serialVersionUID = -5250436858756163721L;

		@SuppressWarnings("unchecked")
		public DisabledItemsComboBox(Map<Integer, ProductInfo> products) {
			super();
			super.setRenderer(new DisabledItemsRenderer());
			addItem(new ProductInfo(0, "", "", "", 0));
			for (ProductInfo productInfo : products.values())
				addItem(productInfo);
		}

		private Set<String> disabled_items = new HashSet<>();

		public Set<String> getDisabledItems() {
			return disabled_items;
		}

		@SuppressWarnings("unused")
		public void addItem(Object anObject, boolean disabled) {
			super.addItem((ProductInfo) anObject);
			disabled_items.add(((ProductInfo) anObject).getName());
		}

		@Override
		public void removeAllItems() {
			super.removeAllItems();
			disabled_items = new HashSet<>();
		}

		@Override
		public void removeItemAt(final int anIndex) {
			super.removeItemAt(anIndex);
			disabled_items.remove(anIndex);
		}

		@Override
		public void removeItem(final Object anObject) {
			for (int i = 0; i < getItemCount(); i++) {
				if (getItemAt(i) == anObject)
					disabled_items.remove(i);
			}
			super.removeItem(anObject);
		}

		@Override
		public void setSelectedIndex(int index) {
			if (!disabled_items.contains(getItemAt(index).getName()))
				super.setSelectedIndex(index);
		}

		private class DisabledItemsRenderer extends BasicComboBoxRenderer {
			private static final long serialVersionUID = -8129296166389246776L;

			@SuppressWarnings("rawtypes")
			@Override
			public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
					boolean cellHasFocus) {

				super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
				String name = value == null ? "" : ((ProductInfo) value).getName();
				if (isSelected) {
					setBackground(list.getSelectionBackground());
					setForeground(list.getSelectionForeground());
				} else {
					setBackground(list.getBackground());
					setForeground(list.getForeground());
				}
				if (disabled_items.contains(name)) {
					setBackground(list.getBackground());
					setForeground(UIManager.getColor("Label.disabledForeground"));
					setText(" -- " + name + " --");
				} else
					setText(name);
				setFont(list.getFont());
				return this;
			}
		}
	}

	private void initGUI() {
		setSize(935, 508);
		setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));

		Component verticalStrut_2 = Box.createVerticalStrut(5);
		add(verticalStrut_2);

		JLabel lblSummary = new JLabel("<html><center>" + mDepartmentData.getName() + "<br>"
				+ mDepartmentData.getAddress1() + ", " + mDepartmentData.getAddress2() + "</center></html>");
		lblSummary.setHorizontalAlignment(SwingConstants.CENTER);
		lblSummary.setFont(new Font("Tahoma", Font.BOLD, 11));
		lblSummary.setAlignmentX(Component.CENTER_ALIGNMENT);
		add(lblSummary);

		Component verticalStrut = Box.createVerticalStrut(5);
		add(verticalStrut);

		JLabel lblPerson = new JLabel(mDepartmentData.getBoss());
		lblPerson.setAlignmentX(Component.CENTER_ALIGNMENT);
		add(lblPerson);

		Component verticalStrut_1 = Box.createVerticalStrut(5);
		add(verticalStrut_1);

		JPanel panel = new JPanel();
		panel.setBackground(SystemColor.window);
		add(panel);
		panel.setLayout(new BorderLayout(0, 0));

		JPanel panel_1 = new JPanel();
		panel_1.setBackground(SystemColor.window);
		panel_1.setBorder(new TitledBorder(null, "Podsumowanie", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		panel.add(panel_1, BorderLayout.SOUTH);
		panel_1.setLayout(new BorderLayout(0, 0));

		JPanel panel_2 = new JPanel();
		panel_2.setMinimumSize(new Dimension(250, 200));
		panel_2.setPreferredSize(new Dimension(300, 200));
		panel_2.setBackground(SystemColor.window);
		panel_2.setBorder(new TitledBorder(null, "Osoba upowa\u017Cniona do odbioru", TitledBorder.LEADING,
				TitledBorder.TOP, null, null));
		panel_1.add(panel_2, BorderLayout.WEST);
		panel_2.setLayout(new FormLayout(new ColumnSpec[] { FormFactory.RELATED_GAP_COLSPEC,
				FormFactory.DEFAULT_COLSPEC, FormFactory.RELATED_GAP_COLSPEC, ColumnSpec.decode("default:grow"),
				FormFactory.RELATED_GAP_COLSPEC, }, new RowSpec[] { FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC, FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC,
				FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC, FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC, FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC,  }));

		JLabel lblNewLabel = new JLabel("Imi\u0119 i nazwisko");
		panel_2.add(lblNewLabel, "2, 2, left, center");

		nameTextField = new JTextField();
		panel_2.add(nameTextField, "4, 2, fill, center");
		nameTextField.setColumns(10);

		JLabel lblNewLabel_1 = new JLabel("Telefon");
		panel_2.add(lblNewLabel_1, "2, 4, left, center");

		phoneTextField = new JTextField();
		panel_2.add(phoneTextField, "4, 4, fill, center");
		phoneTextField.setColumns(10);

		JLabel lblNewLabel_2 = new JLabel("Data dostawy");
		panel_2.add(lblNewLabel_2, "2, 6, left, center");

		datePicker = new DatePicker();
		panel_2.add(datePicker, "4, 6, fill, center");
		
		JLabel lblgaDataDostawy = new JLabel("2ga data dostawy");
		panel_2.add(lblgaDataDostawy, "2, 8");

		datePicker2 = new DatePicker();
		panel_2.add(datePicker2, "4, 8, fill, center");

		JLabel lblNewLabel_3 = new JLabel("Godziny dostaw");
		panel_2.add(lblNewLabel_3, "2, 10, left, center");

		hourTextField = new JTextField();
		panel_2.add(hourTextField, "4, 10, fill, center");
		hourTextField.setColumns(10);
		
		JPanel panel_3 = new JPanel();
		panel_3.setBackground(SystemColor.window);
		panel_3.setBorder(new TitledBorder(null, "Uwagi", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		panel_1.add(panel_3, BorderLayout.CENTER);
		panel_3.setLayout(new GridLayout(0, 1, 0, 0));

		commentsTextPane = new JTextPane();
		panel_3.add(new JScrollPane(commentsTextPane));

		JPanel panel_4 = new JPanel();
		panel_4.setMinimumSize(new Dimension(150, 135));
		panel_4.setPreferredSize(new Dimension(200, 135));
		panel_4.setBackground(SystemColor.window);
		panel_4.setBorder(new TitledBorder(null, "Warto\u015Bci obliczone", TitledBorder.LEADING, TitledBorder.TOP,
				null, null));
		panel_1.add(panel_4, BorderLayout.EAST);
		panel_4.setLayout(new FormLayout(new ColumnSpec[] { FormFactory.RELATED_GAP_COLSPEC,
				FormFactory.DEFAULT_COLSPEC, FormFactory.RELATED_GAP_COLSPEC, ColumnSpec.decode("default:grow"),
				FormFactory.RELATED_GAP_COLSPEC, FormFactory.DEFAULT_COLSPEC, FormFactory.RELATED_GAP_COLSPEC, },
				new RowSpec[] { RowSpec.decode("min:grow"), FormFactory.RELATED_GAP_ROWSPEC,
						FormFactory.DEFAULT_ROWSPEC, FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC,
						FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC, FormFactory.RELATED_GAP_ROWSPEC,
						RowSpec.decode("min:grow"), }));

		JLabel lblNormatyw = new JLabel("Normatyw");
		panel_4.add(lblNormatyw, "2, 3, left, center");

		JLabel lblNorm = new JLabel(String.format("%1$,.2f", mDepartmentData.getNorm()));
		lblNorm.setHorizontalAlignment(SwingConstants.RIGHT);
		panel_4.add(lblNorm, "4, 3");

		JLabel lblCurrency1 = new JLabel("z\u0142");
		lblCurrency1.setHorizontalAlignment(SwingConstants.LEFT);
		panel_4.add(lblCurrency1, "6, 3");

		JLabel lblSuma = new JLabel("Suma");
		panel_4.add(lblSuma, "2, 5, left, center");

		lblSum = new JLabel("0,00");
		lblSum.setHorizontalAlignment(SwingConstants.RIGHT);
		panel_4.add(lblSum, "4, 5");

		JLabel lblCurrency2 = new JLabel("z\u0142");
		lblCurrency2.setHorizontalAlignment(SwingConstants.LEFT);
		panel_4.add(lblCurrency2, "6, 5");

		JLabel lblWTymRefaktura = new JLabel("w tym refaktura");
		panel_4.add(lblWTymRefaktura, "2, 7, left, center");

		lblReInvoice = new JLabel("0,00");
		lblReInvoice.setHorizontalAlignment(SwingConstants.RIGHT);
		panel_4.add(lblReInvoice, "4, 7");

		JLabel lblCurrency3 = new JLabel("z\u0142");
		lblCurrency3.setHorizontalAlignment(SwingConstants.LEFT);
		panel_4.add(lblCurrency3, "6, 7");

		mTable = new JTable();

		final DisabledItemsComboBox combo = new DisabledItemsComboBox(MainPanel.getProducts());

		mTable.setRowSelectionAllowed(false);
		mTable.setRowHeight(mTable.getFontMetrics(mTable.getFont()).getHeight() + 10);
		mTable.setDefaultRenderer(Object.class, new MyTableCellRenderer());
		mTable.setModel(new DefaultTableModel(new Object[][] { { 1, null, null, null, null, null, null, null }, },
				new String[] { "ID", "Nazwa, opis", "Kod towaru", "Ilo\u015B\u0107", "JM", "Cena netto",
						"Warto\u015B\u0107 netto", "Refaktura" }) {
			private static final long serialVersionUID = 1L;

			@SuppressWarnings("rawtypes")
			Class[] columnTypes = new Class[] { Integer.class, String.class, String.class, Integer.class, String.class,
					Double.class, Double.class, Boolean.class };

			@Override
			public boolean isCellEditable(int row, int col) {
				if (!mParent.isOrderEditable())
					return false;
				if (getValueAt(row, 1) == null || ((ProductInfo) getValueAt(row, 1)).getName().isEmpty())
					return col == 1;
				return col == 1 || col == 3 || col == 7;
			}

			@Override
			public void addRow(Object[] rowData) {
				Object[] wtf = new Object[rowData.length + 1];
				wtf[0] = getRowCount() + 1;
				for (int i = 0; i < rowData.length; ++i)
					wtf[i + 1] = rowData[i];
				super.addRow(wtf);
			}

			@Override
			public void removeRow(int row) {
				for (int i = row + 1; i < getRowCount(); ++i)
					setValueAt(i, i, 0);
				double sum = 0;
				Double tmp = null;
				for (int i = 0; i < getRowCount(); ++i) {
					tmp = (Double) getValueAt(i, 6);
					if (tmp != null)
						sum += ((Double) getValueAt(i, 6)).doubleValue();
				}
				lblSum.setText(String.format("%1$,.2f", sum));

				sum = 0;
				for (int i = 0; i < getRowCount(); ++i) {
					if (getValueAt(i, 7) != null && (Boolean) getValueAt(i, 7)) {
						tmp = (Double) getValueAt(i, 6);
						sum += tmp;
					}
				}
				lblReInvoice.setText(String.format("%1$,.2f", sum));
				super.removeRow(row);
			}

			@SuppressWarnings({ "unchecked", "rawtypes" })
			public Class getColumnClass(int columnIndex) {
				return columnTypes[columnIndex];
			}

			@Override
			public void setValueAt(Object aValue, int row, int column) {
				if (aValue == null)
					return;
				if (column == 1) {
					ProductInfo oldValue = (ProductInfo) getValueAt(row, column);
					ProductInfo tmp = (ProductInfo) aValue;
					super.setValueAt(aValue, row, column);
					super.setValueAt(tmp.getIndex(), row, column + 1);
					super.setValueAt(null, row, column + 2);
					super.setValueAt(tmp.getUnit(), row, column + 3);
					super.setValueAt(tmp.getName() == "" ? null : tmp.getPrice(), row, column + 4);
					super.setValueAt(null, row, column + 5);
					super.setValueAt(false, row, column + 6);
					if (oldValue == null || !oldValue.getName().equals(tmp.getName())) {
						if (tmp.getName().isEmpty()) {
							if (getRowCount() > 1)
								removeRow(row);
							if (combo.getDisabledItems().size() == getRowCount() + 1)
								addRow(new Object[] { null, null, null, null, null, null, null });
							if (oldValue != null)
								combo.getDisabledItems().remove(oldValue.getName());
						} else {
							if (getRowCount() - 1 == row && combo.getItemCount() > getRowCount() + 1)
								addRow(new Object[] { null, null, null, null, null, null, null });
							combo.getDisabledItems().add(tmp.getName());
						}
					}
				} else if (column == 3) {
					super.setValueAt(aValue, row, column);
					super.setValueAt((Integer) aValue * (double) getValueAt(row, 5), row, 6);

					double sum = 0;
					Double tmp = null;
					for (int i = 0; i < getRowCount(); ++i) {
						tmp = (Double) getValueAt(i, 6);
						if (tmp != null)
							sum += ((Double) getValueAt(i, 6)).doubleValue();
					}
					lblSum.setText(String.format("%1$,.2f", sum));

					sum = 0;
					for (int i = 0; i < getRowCount(); ++i) {
						if (getValueAt(i, 7) != null && (Boolean) getValueAt(i, 7)) {
							tmp = (Double) getValueAt(i, 6);
							sum += tmp;
						}
					}
					lblReInvoice.setText(String.format("%1$,.2f", sum));
				} else if (column == 7) {
					super.setValueAt(aValue, row, column);
					double sum = 0;
					Double tmp = null;
					for (int i = 0; i < getRowCount(); ++i) {
						if (getValueAt(i, 7) != null && (Boolean) getValueAt(i, 7)) {
							tmp = (Double) getValueAt(i, 6);
							if (tmp != null)
								sum += tmp;
						}
					}
					lblReInvoice.setText(String.format("%1$,.2f", sum));
				} else
					super.setValueAt(aValue, row, column);
				// mTca.adjustColumns();
			}
		});

		DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
		centerRenderer.setHorizontalAlignment(JLabel.CENTER);
		mTable.getColumnModel().getColumn(0).setCellRenderer(centerRenderer);
		mTable.getColumnModel().getColumn(1).setCellEditor(new DefaultCellEditor(combo));
		mTable.getColumnModel().getColumn(4).setCellRenderer(centerRenderer);

		mTable.getColumnModel().getColumn(0).setMaxWidth(30);
		mTable.getColumnModel().getColumn(1).setPreferredWidth(190);
		mTable.getColumnModel().getColumn(3).setPreferredWidth(35);
		mTable.getColumnModel().getColumn(4).setPreferredWidth(35);
		mTable.getColumnModel().getColumn(6).setMinWidth(85);
		mTable.getColumnModel().getColumn(7).setMaxWidth(65);
		mTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);

		// mTca = new TableColumnAdjuster(mTable);
		// mTca.adjustColumns();

		mTable.setBackground(SystemColor.window);
		JScrollPane scrollPane = new JScrollPane(mTable);
		panel.add(scrollPane, BorderLayout.CENTER);
	}
	
	private class MyTableCellRenderer extends DefaultTableCellRenderer {
		private static final long serialVersionUID = -736646884303511128L;

		@Override
		public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
				int row, int column) {
			
			if (value instanceof ProductInfo)
				value = ((ProductInfo)value).getName();
			return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
		}
	}
}
